import re
import time
import requests

from django.shortcuts import render
from django.db.models import Q
from rest_framework.views import APIView
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter

from middlewares.auth import auth_middleware, login_and_auth_middleware, image_cache_middleware
from middlewares.auto_speed import speed_limit_middleware, log_middleware
from admin_app.serializers import UserSimpleSerializer, ArticleSimpleSerializer

from article_app import models as a_models
from user_app import models as u_models
from admin_app.filters import UserFilter, ArticleFilter


from configer import EMAIL_SERVE_HOST, EMAIL_SERVE_PASS
from utils.encode_decode import bw_encode
from utils.pagination import MyPageNumberPagination, MyPageNumberPaginationCursor, MySingalPageNumberPaginationCursor
# Create your views here.
from utils.encode_decode import my_decode
from utils.encode_decode import ShortLink

# 猴子补丁
my_decode = ShortLink().decrypt

class UserView(APIView):
    """负责获取全部用户和注册"""
    
    # #DjangoFilterBackend表示开启筛选，OrderingFilter表示开启排序
    # filter_backends = [DjangoFilterBackend, OrderingFilter]
    filter_backends = [DjangoFilterBackend, OrderingFilter]

    def filter_queryset(self, queryset):
        for backend in list(self.filter_backends):
            queryset = backend().filter_queryset(self.request, queryset, self)
        return queryset

    filter_class = UserFilter
    ordering = ('-level', '-register_time')

    @log_middleware
    @speed_limit_middleware
    @login_and_auth_middleware
    @auth_middleware(10)
    def get(self, request):
        """查看用户个人信息 但是只能看到Level比自己小的用户信息"""
        pagination_class = MyPageNumberPaginationCursor()
        uid = request.META["mini_uid"]
        user = u_models.User.objects.get(pk=uid)
        # 只能查看比自己等级的用户 除了站长
        if "站长" in user.tags.split('|'):
            users = u_models.User.objects.all()
        else:
            users = u_models.User.objects.filter(~Q(id=uid) & Q(level__lte=user.level)).all()
        f = UserFilter(request.GET, queryset=users)  # 条件过滤
        pager_roles = pagination_class.paginate_queryset(queryset=f.qs, request=request, view=self)
        bs = UserSimpleSerializer(pager_roles, many=True)
        return pagination_class.get_paginated_response(bs.data)
    
    @log_middleware
    @login_and_auth_middleware
    @auth_middleware(10)
    def put(self, request):
        """改变用户状态"""
        allow_method = ['is_valid', 'avatar', 'send_message', 'send_email']
        uid = request.META["mini_uid"]
        user = u_models.User.objects.get(pk=uid)
        aim_id = self.decode_id(request.data.get('aim_id', None))
        method_args = request.data.get('method_args', 'recommend')
        tag = request.data.get('tag', None)
        word =  request.data.get('word', None)
        if not aim_id or not u_models.User.objects.filter(pk=aim_id).exists():
            return Response({"message": "用户不存在", "code": 3001})
        if method_args not in allow_method:
            return Response({"message": "参数不被允许", "code": 3001})
        if not tag or not re.match('^-?\d+$', tag):
            return Response({"message": "参数不正确", "code": 3001})
        tag = int(tag)  # 强转类型
        aim_user = u_models.User.objects.get(pk=aim_id)
        if method_args == 'is_valid' and tag in range(2):
            aim_user.is_valid = tag
            aim_user.save()
            # new_message = a_models.Message(from_id=0, to_id=aim_user.id, info=f'取消系统禁用' if tag else f'被系统禁用', need_reply=0, link=0, link_com=0, message_type="系统消息", add_time=time.time())
            # new_message.save()
            return Response({"message": "修改成功", "code": 200})
        elif method_args == 'avatar':
            aim_user.avatar = '/static/image/default.jpg'
            aim_user.save()
            new_message = a_models.Message(from_id=0, to_id=aim_user.id, info=f'头像不符合社区规定，已被重置', need_reply=0, link=0, link_com=0, message_type="系统消息", add_time=time.time())
            new_message.save()
            return Response({"message": "修改成功", "code": 200})
        elif method_args == 'send_message' and word and len(word.strip()) > 0:
            new_message = a_models.Message(from_id=user.id, to_id=aim_user.id, info=word, need_reply=1, link=0, link_com=0, message_type="管理员消息", add_time=time.time())
            new_message.save()
            return Response({"message": "修改成功", "code": 200})
        elif method_args == 'send_email' and len(word) > 2:
            # 发送邮件 需要等级大于10
            if user.level > 10:
                res = self.send(user.nick_name, aim_user.email, word)
                return Response({"message": f"发送{'成功' if res else '失败'}", "code": 200 if res else 3001})
            else:
                return Response({"message": "没有相关权限", "code": 3001})

        return Response({"message": "参数不正确", "code": 3001})
    
    def send(self, nick_name, email, word):
        """发送邮件"""
        retry_count = 3
        while retry_count:
            try:
                payload = {
                    "email": email,
                    "info": f'【黑白空间】来自管理员 {nick_name} 留言：{word}',
                    "pass": EMAIL_SERVE_PASS
                }
                res = requests.post(f'http://{EMAIL_SERVE_HOST}/', data=payload)
                print(res.status_code)
            except Exception as e:
                retry_count -= 1
                continue
            if res.status_code == 200:
                return True
        return False
    
    @staticmethod
    def decode_id(id_):
        if not id_:
            return None
        id_ = int(my_decode(id_))
        return id_ if id_ > 0 else -1
    
    
    

class ArticleView(APIView):
    """查看所有文章"""
    
    # #DjangoFilterBackend表示开启筛选，OrderingFilter表示开启排序
    # filter_backends = [DjangoFilterBackend, OrderingFilter]
    filter_backends = [DjangoFilterBackend, OrderingFilter]

    def filter_queryset(self, queryset):
        for backend in list(self.filter_backends):
            queryset = backend().filter_queryset(self.request, queryset, self)
        return queryset

    filter_class = ArticleFilter
    ordering = ('-recommend', '-view_no', '-add_time')
    
    
    
    @log_middleware
    @login_and_auth_middleware
    @auth_middleware(10)
    def get(self, request):
        """查看文章"""
        pagination_class = MyPageNumberPaginationCursor()
        uid = request.META["mini_uid"]
        user = u_models.User.objects.get(pk=uid)
        # 排除自己的文章以及等级比自己高的用户的文章
        if "站长" in user.tags.split('|'):
            articles = a_models.Article.objects.filter(is_delete=0).select_related('u_id').all()
        else:
            articles = a_models.Article.objects.filter(~Q(u_id__id__in=[uid]) & Q(u_id__level__lte=user.level) & Q(is_delete=0)).select_related('u_id').all()
        f = ArticleFilter(request.GET, queryset=articles)  # 条件过滤
        pager_roles = pagination_class.paginate_queryset(queryset=f.qs, request=request, view=self)
        bs = ArticleSimpleSerializer(pager_roles, many=True)
        return pagination_class.get_paginated_response(bs.data)
    
    @log_middleware
    @login_and_auth_middleware
    @auth_middleware(10)
    def put(self, request):
        """改变文章状态"""
        allow_method = ['recommend', 'is_recommend', 'is_check', 'is_valid', 'head_avatar']
        uid = request.META["mini_uid"]
        user = u_models.User.objects.get(pk=uid)
        aid = self.decode_id(request.data.get('aid', None))
        method_args = request.data.get('method_args', 'recommend')
        tag = request.data.get('tag', None)
        word =  request.data.get('word', None)
        if not aid or not a_models.Article.objects.filter(pk=aid).exists():
            return Response({"message": "文章不存在", "code": 3001})
        if method_args not in allow_method:
            return Response({"message": "参数不被允许", "code": 3001})
        if not tag or not re.match('^-?\d+$', tag):
            return Response({"message": "参数不正确", "code": 3001})
        tag = int(tag)  # 强转类型
        article = a_models.Article.objects.get(pk=aid)  # 文章实体
        if method_args == 'recommend' and tag in range(11):
            article.recommend = tag
            article.save()
            new_message = a_models.Message(from_id=0, to_id=article.u_id.id, info=f'{article.title} 文章推荐等级调整为Lv{tag}', need_reply=0, link=article.id, link_com=0, message_type="系统消息", add_time=time.time())
            new_message.save()
            return Response({"message": "修改成功", "code": 200})
        elif method_args == 'is_recommend' and tag in range(2):
            article.is_recommend = tag
            article.save()
            new_message = a_models.Message(from_id=0, to_id=article.u_id.id, info=f'{article.title} 上热门' if tag else f'{article.title} 取消热门', need_reply=0, link=article.id, link_com=0, message_type="系统消息", add_time=time.time())
            new_message.save()
            return Response({"message": "修改成功", "code": 200})
        elif method_args == 'head_avatar':
            article.head_avatar = '/static/image/default.jpg'
            article.save()
            new_message = a_models.Message(from_id=0, to_id=article.u_id.id, info=f'封面不符合社区规定，已被重置', need_reply=0, link=0, link_com=0, message_type="系统消息", add_time=time.time())
            new_message.save()
            return Response({"message": "修改成功", "code": 200})
        elif method_args == 'is_check' and tag in range(-1, 2):
            article.is_check = tag
            article.save()
            if tag == 0:
                info = "审核"
            elif tag == 1:
                info = "通过"
            else:
                info = "驳回"
            if word == 'null':
                word = ''
            new_message = a_models.Message(from_id=0, to_id=article.u_id.id, info=f'{article.title} 文章状态置为{info} 原因：{word}', need_reply=0, link=article.id, link_com=0, message_type="系统消息", add_time=time.time())
            new_message.save()
            return Response({"message": "修改成功", "code": 200})
        elif method_args == 'is_valid' and tag in range(2):
            article.is_valid = tag
            article.save()
            new_message = a_models.Message(from_id=0, to_id=article.u_id.id, info=f'{article.title} 取消禁用' if tag else f'{article.title} 被系统禁用', need_reply=0, link=article.id, link_com=0, message_type="系统消息", add_time=time.time())
            new_message.save()
            return Response({"message": "修改成功", "code": 200})
        return Response({"message": "参数不正确", "code": 3001})
    
    @staticmethod
    def decode_id(id_):
        if not id_:
            return None
        id_ = int(my_decode(id_))
        return id_ if id_ > 0 else -1